Skip to content

feat(structure-lock): freeze root layout + CI gate + pre-commit — pilot (FIVUCSAS#209)#210

Merged
ahmetabdullahgultekin merged 1 commit into
masterfrom
feat/repo-structure-lock
Jun 13, 2026
Merged

feat(structure-lock): freeze root layout + CI gate + pre-commit — pilot (FIVUCSAS#209)#210
ahmetabdullahgultekin merged 1 commit into
masterfrom
feat/repo-structure-lock

Conversation

@ahmetabdullahgultekin

Copy link
Copy Markdown
Contributor

What

Pilots the repo structure-lock (ArchUnit-style FREEZE of the root file/folder layout) on the umbrella repo. Closes #209 once the owner sets the required check (below).

It blocks — when a disallowed/forbidden file appears at the root (e.g. a stray dated tracking doc), the PR's structure-check goes red. It does not silently auto-move anything.

Depends on Rollingcat-Software/.github#2 (the reusable workflow + stdlib check script). Merge that PR first, or the caller's uses: ref won't resolve.

Contents

File Purpose
.repo-structure.yml Allowlists frozen from the current clean origin/master root (16 root files, 20 root dirs) + forbidden_root_patterns + required_files.
.github/workflows/structure-check.yml Thin caller of the org reusable workflow on pull_request.
.pre-commit-config.yaml Adds the repo-structure hook (from the .github repo) alongside the existing gitleaks hook.

The forbidden patterns encode the convention "tracking → GitHub issues, NOT root docs":

forbidden_root_patterns:
  - '.*_(AUDIT|REVIEW|FINDINGS|REGISTER|TRIAGE|SWEEP|STATUS|SESSION|RECONCILIATION)_.*\.md$'
  - '.*_\d{4}-\d{2}-\d{2}.*\.md$'
  - '^(TODO|ROADMAP|BACKLOG|OPERATOR_TODO|PERSONAL_TODO).*\.md$'

Proof

# clean current root
$ python3 check_repo_structure.py --root .
Repo structure-lock PASSED — root layout matches .repo-structure.yml.   (exit 0)

# planted dummy
$ : > TEST_AUDIT_2026-06-13.md
$ python3 check_repo_structure.py --root .
Repo structure-lock FAILED (1 violation):
  - FORBIDDEN: root entry 'TEST_AUDIT_2026-06-13.md' matches forbidden pattern
    /.*_(AUDIT|REVIEW|FINDINGS|REGISTER|TRIAGE|SWEEP|STATUS|SESSION|RECONCILIATION)_.*\.md$/
(exit 1)
# dummy removed — back to PASS.

Local use

pip install pre-commit        # or pipx
./.pre-commit-install         # installs gitleaks + repo-structure in parent + submodules
# now `git commit` runs the structure-lock locally before accepting the commit.
# one-off:  python3 -m ... or run the hook via `pre-commit run repo-structure --all-files`

Rollout to the 7 submodules

Each submodule gets the same two files, frozen from its own root:

  1. In a clean clone of the submodule (gh repo clone Rollingcat-Software/<repo>), add .repo-structure.yml listing exactly the current root files/dirs (the frozen baseline) + the same forbidden_root_patterns block above + required_files (at least README.md).
  2. Add .github/workflows/structure-check.yml:
    name: structure-check
    on:
      pull_request:
    jobs:
      repo-structure:
        uses: Rollingcat-Software/.github/.github/workflows/repo-structure.yml@main
  3. (Optional) add the pre-commit hook to the submodule's .pre-commit-config.yaml:
    - repo: https://github.com/Rollingcat-Software/.github
      rev: main
      hooks:
        - id: repo-structure
  4. Open a PR; confirm structure-check passes on the clean root.

The 7 submodules: identity-core-api, biometric-processor, web-app, client-apps, spoof-detector, docs, practice-and-test.

One manual OWNER step (makes it actually block)

After this PR's structure-check has run at least once (so GitHub knows the check name), add it as a required status check on master:

# adds "structure-check" to existing required checks (keep review requirement)
gh api -X PATCH repos/Rollingcat-Software/FIVUCSAS/branches/master/protection/required_status_checks \
  -f strict=false -f 'checks[][context]=structure-check'

# verify
gh api repos/Rollingcat-Software/FIVUCSAS/branches/master/protection/required_status_checks

(The check context surfaces as structure-check — the caller job name. If GitHub shows it nested as repo-structure / structure-check, use that exact string. Confirm the displayed name on the first PR run, then add it.) Repeat per submodule on its default branch (main).

Do not merge until reviewed.

…CSAS#209)

Pilot the org repo structure-lock on the umbrella repo.

- .repo-structure.yml: allowlists FROZEN from the current clean origin/master
  root (16 root files + 20 root dirs) + forbidden_root_patterns so dated
  tracking docs (*_AUDIT_*, *_2026-06-13*, TODO*/ROADMAP*/BACKLOG*) can never
  reappear at root + required_files (README/LICENSE/.gitignore).
- .github/workflows/structure-check.yml: thin caller of the org reusable
  workflow Rollingcat-Software/.github .github/workflows/repo-structure.yml@main,
  on pull_request. FAILS the PR on any layout drift.
- .pre-commit-config.yaml: add the `repo-structure` hook from the .github repo
  for fast local feedback mirroring the CI gate.

Verified: check PASSES on the current clean root (exit 0) and FAILS on a
planted TEST_AUDIT_2026-06-13.md (exit 1, FORBIDDEN). Dummy removed.

Depends on Rollingcat-Software/.github#2 (reusable workflow + script).
@ahmetabdullahgultekin

Copy link
Copy Markdown
Contributor Author

Note on the red structure-check here: it fails with "This run likely failed because of a workflow file issue" and 0s duration — this is not a layout violation. The caller does uses: Rollingcat-Software/.github/.github/workflows/repo-structure.yml@main, and that reusable workflow only exists on the feat/repo-structure-lock branch of the .github repo so far (PR Rollingcat-Software/.github#2). The @main ref can't resolve until that PR merges.

Order of operations:

  1. Merge feat(structure-lock): org reusable workflow + stdlib check script (FIVUCSAS#209) .github#2 to main (reusable workflow + script land).
  2. Re-run this PR's structure-check — it will resolve @main and run the gate. On this clean root it passes (exit 0).

Proof the mechanism works end-to-end (independent of this ordering): the .github repo runs the same reusable workflow against itself and is now green — see the structure-check success on Rollingcat-Software/.github#2. The earlier red run there caught (and the fix addressed) a real bug: the tooling-checkout dir was being flagged.

Locally, against this PR's exact tree: clean root → PASS (exit 0); planted TEST_AUDIT_2026-06-13.md → FAIL (exit 1, FORBIDDEN).

@ahmetabdullahgultekin ahmetabdullahgultekin merged commit 760259e into master Jun 13, 2026
1 check passed
@ahmetabdullahgultekin ahmetabdullahgultekin deleted the feat/repo-structure-lock branch June 13, 2026 09:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Repo structure-lock: declarative policy + CI gate (ArchUnit-analog for file/folder layout)

1 participant